Skip to content

fix(repeater/sensor/room_server/secure_chat cli): permanent lockup without CR - #2978

Open
fkallay1 wants to merge 1 commit into
meshcore-dev:devfrom
fkallay1:fix/serial-cli-buffer-lockup
Open

fix(repeater/sensor/room_server/secure_chat cli): permanent lockup without CR#2978
fkallay1 wants to merge 1 commit into
meshcore-dev:devfrom
fkallay1:fix/serial-cli-buffer-lockup

Conversation

@fkallay1

@fkallay1 fkallay1 commented Jul 18, 2026

Copy link
Copy Markdown

Note on scope: these four live under examples/, but they are the shipped repeater, sensor, room
server and secure chat firmwares - the same ones the "Build ... Firmwares" workflows produce - so
this is not a samples-only fix.

Problem

The serial CLI loop in the examples locks up permanently when ≥159 characters arrive without a CR. The buffer-full branch tries to force-complete the line:

if (len == sizeof(command)-1) {  // command buffer full
    command[sizeof(command)-1] = '\r';
}

but the line-complete check below tests command[len - 1], which is command[sizeof-2] when the buffer is full — one position before the byte just written. The result:

  1. The line never completes, so the buffer is never reset.
  2. The read loop's condition (len < sizeof(command)-1) stays false forever — the CLI stops reading serial input entirely until reboot. Everything else (mesh, radio) keeps running, so the node looks alive but ignores all commands.
  3. Writing at [sizeof-1] also overwrites the string's NUL terminator, so the next strlen(command) reads past the end of the buffer (UB).

How it triggers in practice

Reproduced on hardware (T1000-E repeater, remote site): the serial console was shared through tmux+picocom, and ~53 arrow-key presses in the attached terminal (3-byte ESC[A escape sequences, 159 bytes with no CR) filled the buffer. The CLI never accepted a command again until the device was rebooted.

Any input source that produces long CR-less byte runs triggers it: pasted text, cursor-key escape sequences, line noise on a hardware UART, or a script sending LF-only line endings (LF is skipped, other bytes accumulate).

Fix

Write the forced '\r' at command[sizeof-2] — exactly the position the completion check tests. The overflowed input is then processed as an (unknown) command, the buffer resets, and the CLI keeps working.

The same copy-pasted pattern exists in four examples; all are fixed:

  • examples/simple_repeater/main.cpp
  • examples/simple_sensor/main.cpp
  • examples/simple_room_server/main.cpp
  • examples/simple_secure_chat/main.cpp

Testing

  • Bug reproduced on hardware (build without the fix): 159 CR-less bytes → CLI dead until reboot.
  • Fix verified on the same hardware (T1000-E repeater): sending 200 CR-less characters force-completes the overflowed line as an unknown command and the very next ver command answers normally.
  • Built t1000e_repeater on this branch (no other changes).

fkallay1 added a commit to fkallay1/MeshCore that referenced this pull request Jul 18, 2026
@fkallay1

fkallay1 commented Jul 29, 2026

Copy link
Copy Markdown
Author

Gentle nudge on this one, no urgency intended.

PR Build Check never started on it, so there is nothing green here for anyone to look at - I think
it is sitting behind the first-time-contributor workflow approval rather than anything in the change
itself. If someone could approve the run, at least it would be reviewable.

For context, the change is one line repeated across the repeater, sensor, room server and secure chat
firmwares: the forced '\r' is written at command[sizeof-1] while the line-complete check tests
command[len-1], so an overlong CR-less line never completes, the buffer never resets, and the CLI
stops reading serial input until reboot. It was reproduced and then verified fixed on hardware
(T1000-E repeater).

Happy to rebase, split it per firmware, or narrow the scope if any of that would make it easier to
take. (I have also retitled it - the original said fix(examples), which undersold it: those four
are the shipped firmwares, not samples.)

@fkallay1 fkallay1 changed the title fix(examples): serial CLI locks up permanently on buffer overflow without CR Fix permanent serial CLI lockup in repeater, sensor, room server and secure chat Jul 29, 2026
@fkallay1 fkallay1 changed the title Fix permanent serial CLI lockup in repeater, sensor, room server and secure chat fix(cli): permanent serial lockup in repeater, sensor, room server, secure chat Jul 29, 2026
@fkallay1 fkallay1 changed the title fix(cli): permanent serial lockup in repeater, sensor, room server, secure chat fix(repeater/sensor/room_server/secure_chat cli): permanent lockup without CR Jul 29, 2026
@fkallay1
fkallay1 force-pushed the fix/serial-cli-buffer-lockup branch from be236e1 to 667e942 Compare July 29, 2026 00:55
…thout CR

The buffer-full branch writes the forced '\r' to command[sizeof-1], but the
line-complete check below tests command[len-1] (== sizeof-2 when the buffer
is full), so the line never completes: the read loop's condition
(len < sizeof-1) stays false forever and the CLI stops reading serial input
until reboot. Writing at [sizeof-1] also overwrites the string's NUL
terminator, so the next strlen() reads past the buffer (UB).

Write the '\r' at command[sizeof-2] instead — exactly the position the
completion check tests. The overflowed input is then processed as an
(unknown) command, the buffer resets, and the CLI keeps working.

Reproduced on hardware (T1000-E repeater): ~53 arrow-key presses in an
attached terminal (3-byte ESC[A escape sequences, 159 bytes with no CR)
filled the buffer and the CLI never accepted a command again until reboot.

The same copy-pasted pattern is fixed in simple_repeater, simple_sensor,
simple_room_server and simple_secure_chat.
@fkallay1
fkallay1 force-pushed the fix/serial-cli-buffer-lockup branch from 667e942 to f76c465 Compare July 29, 2026 00:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant